package com.jiazixuan.stock.security.service;

import com.jiazixuan.stock.mapper.SysPermissionMapper;
import com.jiazixuan.stock.mapper.SysRoleMapper;
import com.jiazixuan.stock.mapper.SysUserMapper;
import com.jiazixuan.stock.mapper.SysUserRoleMapper;
import com.jiazixuan.stock.pojo.domain.MenusPermDomain;
import com.jiazixuan.stock.pojo.entity.SysPermission;
import com.jiazixuan.stock.pojo.entity.SysRole;
import com.jiazixuan.stock.pojo.entity.SysUser;
import com.jiazixuan.stock.security.user.LoginUserDetail;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service("userDetailsService")
public class LoginUserDetailServie implements UserDetailsService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysPermissionMapper sysPermissionMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;


    /**
     * 根据传入的用户名获取用户相关的详情信息：用户名，密文密码，权限集合等
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.根据用户名称获取数据库中用户的核心信息
        SysUser dbUser = sysUserMapper.findUserInfoByUserName(username);
        if (dbUser==null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        //2.组装UserDetails对象
        //2.1 思考：需要哪些字段？用户名，密文密码，权限集合（web接口绑定表示的集合）等
        //2.2 其他字段：id email phone menus permissions 等
        //根据用户id查找角色id（集合）
        List<Long> roleId = sysUserRoleMapper.getRoleIdByUserId(dbUser.getId());
        //根据角色id获取权限（集合）
        List<SysPermission> permissions = sysPermissionMapper.getPermissionByRoleId(roleId);
        //根据角色id获取角色信息
        List<SysRole> roles = sysRoleMapper.getRoleMsgByRoleId(roleId);
        //递归获取菜单权限过滤掉按钮权限
        List<MenusPermDomain> menus = MenusPermDomain.digui(permissions,0l);
        //获取按钮权限
        List<String> ButtonPermission = permissions.stream()
                .filter(p -> p.getType().intValue() == 3)
                .map(p -> p.getCode())
                .collect(Collectors.toList());
        //获取springSecurity的权限表示 ROLE_角色名称 + 权限自身表示
        ArrayList<String> ps = new ArrayList<>();
        List<String> pers = permissions.stream().filter(per -> StringUtils.isNotBlank(per.getPerms()))
                .map(per -> per.getPerms())
                .collect(Collectors.toList());
        ps.addAll(pers);
        //获取角色信息中的名字
        List<String> roleNames = roles.stream().map(role -> "ROLE_" + role.getName()).collect(Collectors.toList());
        ps.addAll(roleNames);
        //将用户拥有的权限标识转权限对象
        String[] psArray = ps.toArray(new String[pers.size()]);
        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(psArray);
        //构建用户详情服务对象
        LoginUserDetail userDetail = new LoginUserDetail();
        //将dbUser复制到详情服务对象
        BeanUtils.copyProperties(dbUser,userDetail);
        userDetail.setMenus(menus);
        userDetail.setPermissions(ButtonPermission);
        userDetail.setAuthorities(authorityList);
        return userDetail;
    }
}
